package main.java.com.healthy.controller;
import main.java.com.healthy.entity.NutritionGoal;
import main.java.com.healthy.entity.User;
import main.java.com.healthy.service.NutritionGoalService;
import main.java.com.healthy.service.UserProfileService;
import main.java.com.healthy.service.impl.NutritionGoalServiceImpl;
import main.java.com.healthy.service.impl.UserProfileServiceImpl;

import java.util.Map;
import java.util.Scanner;

/**
 * 用户档案管理控制器
 * 对应功能模块：个人健康档案管理、营养目标与计划模块
 */
public class UserProfileController {
    private UserProfileService profileService;
    private NutritionGoalService goalService;
    private Scanner scanner;

    public UserProfileController() {
        this.profileService = new UserProfileServiceImpl();
        this.goalService = new NutritionGoalServiceImpl();
        this.scanner = new Scanner(System.in);
    }

    /**
     * 管理用户档案
     */
    public void manageUserProfile(User user) {
        while (true) {
            System.out.println("\n=== 个人档案管理 ===");
            showUserProfile(user);
            System.out.println("\n请选择操作:");
            System.out.println("1. 修改个人信息");
            System.out.println("2. 设置营养目标");
            System.out.println("3. 查看营养目标");
            System.out.println("4. 计算热量需求");
            System.out.println("5. 返回主菜单");
            System.out.print("请选择: ");

            String choice = scanner.nextLine().trim();

            switch (choice) {
                case "1":
                    updateUserProfile(user);
                    break;
                case "2":
                    setNutritionGoal(user);
                    break;
                case "3":
                    viewNutritionGoal(user);
                    break;
                case "4":
                    calculateCalorieNeeds(user);
                    break;
                case "5":
                    return;
                default:
                    System.out.println("无效选择，请重新输入！");
            }
        }
    }

    /**
     * 显示用户档案
     */
    public void showUserProfile(User user) {
        System.out.println("=== 个人信息 ===");
        System.out.println("用户名: " + user.getUsername());
        System.out.println("性别: " + user.getGender());
        System.out.println("年龄: " + user.getAge() + " 岁");
        System.out.println("身高: " + user.getHeight() + " cm");
        System.out.println("体重: " + user.getWeight() + " kg");
        System.out.println("BMI: " + String.format("%.1f", user.getBmi()) +
                " (" + user.getBmiCategory() + ")");
        System.out.println("活动水平: " + user.getActivityLevel());
        System.out.println("目标: " + user.getTarget());

        double bmr = profileService.calculateBMR(user);
        double dailyNeeds = profileService.calculateDailyCalorieNeeds(user);
        System.out.println("基础代谢率(BMR): " + String.format("%.0f", bmr) + " 千卡/天");
        System.out.println("每日热量需求: " + String.format("%.0f", dailyNeeds) + " 千卡/天");
    }

    /**
     * 更新用户档案
     */
    private void updateUserProfile(User user) {
        System.out.println("\n=== 修改个人信息 ===");

        System.out.print("请输入身高(cm) [" + user.getHeight() + "]: ");
        String heightInput = scanner.nextLine().trim();
        if (!heightInput.isEmpty()) {
            try {
                double height = Double.parseDouble(heightInput);
                if (height >= 100 && height <= 250) {
                    user.setHeight(height);
                } else {
                    System.out.println("身高应在100-250cm之间，保持原值");
                }
            } catch (NumberFormatException e) {
                System.out.println("输入格式错误，保持原值");
            }
        }

        System.out.print("请输入体重(kg) [" + user.getWeight() + "]: ");
        String weightInput = scanner.nextLine().trim();
        if (!weightInput.isEmpty()) {
            try {
                double weight = Double.parseDouble(weightInput);
                if (weight >= 30 && weight <= 200) {
                    user.setWeight(weight);
                } else {
                    System.out.println("体重应在30-200kg之间，保持原值");
                }
            } catch (NumberFormatException e) {
                System.out.println("输入格式错误，保持原值");
            }
        }

        System.out.print("请输入年龄 [" + user.getAge() + "]: ");
        String ageInput = scanner.nextLine().trim();
        if (!ageInput.isEmpty()) {
            try {
                int age = Integer.parseInt(ageInput);
                if (age >= 10 && age <= 100) {
                    user.setAge(age);
                } else {
                    System.out.println("年龄应在10-100岁之间，保持原值");
                }
            } catch (NumberFormatException e) {
                System.out.println("输入格式错误，保持原值");
            }
        }

        System.out.println("请选择活动水平:");
        System.out.println("1. 久坐（办公室工作，很少运动）");
        System.out.println("2. 轻度活动（每周1-3天轻度运动）");
        System.out.println("3. 中度活动（每周3-5天中度运动）");
        System.out.println("4. 重度活动（每周6-7天高强度运动）");
        System.out.println("5. 极重度活动（体力劳动者或专业运动员）");
        System.out.print("请选择(1-5) [当前: " + getActivityLevelCode(user.getActivityLevel()) + "]: ");

        String activityInput = scanner.nextLine().trim();
        if (!activityInput.isEmpty()) {
            try {
                int activityChoice = Integer.parseInt(activityInput);
                if (activityChoice >= 1 && activityChoice <= 5) {
                    switch (activityChoice) {
                        case 1: user.setActivityLevel("久坐"); break;
                        case 2: user.setActivityLevel("轻度活动"); break;
                        case 3: user.setActivityLevel("中度活动"); break;
                        case 4: user.setActivityLevel("重度活动"); break;
                        case 5: user.setActivityLevel("极重度活动"); break;
                    }
                }
            } catch (NumberFormatException e) {
                System.out.println("输入格式错误，保持原值");
            }
        }

        System.out.println("请选择目标:");
        System.out.println("1. 减重");
        System.out.println("2. 维持");
        System.out.println("3. 增肌");
        System.out.print("请选择(1-3) [当前: " + getTargetCode(user.getTarget()) + "]: ");

        String targetInput = scanner.nextLine().trim();
        if (!targetInput.isEmpty()) {
            try {
                int targetChoice = Integer.parseInt(targetInput);
                if (targetChoice >= 1 && targetChoice <= 3) {
                    switch (targetChoice) {
                        case 1: user.setTarget("减重"); break;
                        case 2: user.setTarget("维持"); break;
                        case 3: user.setTarget("增肌"); break;
                    }
                }
            } catch (NumberFormatException e) {
                System.out.println("输入格式错误，保持原值");
            }
        }

        // 更新用户信息
        if (profileService.updateUserProfile(user)) {
            System.out.println("个人信息更新成功！");
            showUserProfile(user);
        } else {
            System.out.println("个人信息更新失败！");
        }
    }

    /**
     * 设置营养目标
     */
    private void setNutritionGoal(User user) {
        System.out.println("\n=== 设置营养目标 ===");

        // 计算推荐目标
        Map<String, Double> recommendedGoals = goalService.calculateRecommendedGoals(user, user.getTarget());

        System.out.println("基于您的个人信息，推荐目标如下:");
        System.out.println("每日热量: " + String.format("%.0f", recommendedGoals.get("calories")) + " 千卡");
        System.out.println("每日碳水: " + String.format("%.0f", recommendedGoals.get("carbs")) + " g");
        System.out.println("每日蛋白质: " + String.format("%.0f", recommendedGoals.get("protein")) + " g");
        System.out.println("每日脂肪: " + String.format("%.0f", recommendedGoals.get("fat")) + " g");

        System.out.print("\n是否使用推荐目标？(y/n): ");
        String useRecommended = scanner.nextLine().trim().toLowerCase();

        double calorieGoal, carbsGoal, proteinGoal, fatGoal;

        if ("y".equals(useRecommended) || "yes".equals(useRecommended)) {
            calorieGoal = recommendedGoals.get("calories");
            carbsGoal = recommendedGoals.get("carbs");
            proteinGoal = recommendedGoals.get("protein");
            fatGoal = recommendedGoals.get("fat");
        } else {
            System.out.print("请输入每日热量目标(千卡): ");
            calorieGoal = getValidDoubleInput(500, 5000);

            System.out.print("请输入每日碳水目标(g): ");
            carbsGoal = getValidDoubleInput(0, 1000);

            System.out.print("请输入每日蛋白质目标(g): ");
            proteinGoal = getValidDoubleInput(0, 500);

            System.out.print("请输入每日脂肪目标(g): ");
            fatGoal = getValidDoubleInput(0, 300);
        }

        NutritionGoal goal = new NutritionGoal();
        goal.setUserId(user.getUserId());
        goal.setDailyCalorieGoal(calorieGoal);
        goal.setDailyCarbsGoal(carbsGoal);
        goal.setDailyProteinGoal(proteinGoal);
        goal.setDailyFatGoal(fatGoal);
        goal.setTargetType(user.getTarget());

        if (goalService.setNutritionGoal(goal)) {
            System.out.println("营养目标设置成功！");
        } else {
            System.out.println("营养目标设置失败！");
        }
    }

    /**
     * 查看营养目标
     */
    private void viewNutritionGoal(User user) {
        System.out.println("\n=== 营养目标 ===");

        NutritionGoal goal = goalService.getNutritionGoal(user.getUserId());
        if (goal == null) {
            System.out.println("您还没有设置营养目标，请先设置营养目标。");
            return;
        }

        System.out.println("每日热量目标: " + String.format("%.0f", goal.getDailyCalorieGoal()) + " 千卡");
        System.out.println("每日碳水目标: " + String.format("%.0f", goal.getDailyCarbsGoal()) + " g");
        System.out.println("每日蛋白质目标: " + String.format("%.0f", goal.getDailyProteinGoal()) + " g");
        System.out.println("每日脂肪目标: " + String.format("%.0f", goal.getDailyFatGoal()) + " g");
        System.out.println("目标类型: " + goal.getTargetType());

        System.out.println("\n宏量营养素比例:");
        System.out.println("碳水: " + String.format("%.1f", goal.getCarbsCaloriePercentage()) + "%");
        System.out.println("蛋白质: " + String.format("%.1f", goal.getProteinCaloriePercentage()) + "%");
        System.out.println("脂肪: " + String.format("%.1f", goal.getFatCaloriePercentage()) + "%");

        if (goal.isValid()) {
            System.out.println("\n✓ 目标设置合理");
        } else {
            System.out.println("\n⚠ 目标设置可能需要调整");
            System.out.println("建议比例: " + goal.getRecommendedDistribution());
        }

        System.out.println("\n按回车键返回...");
        scanner.nextLine();
    }

    /**
     * 计算热量需求
     */
    private void calculateCalorieNeeds(User user) {
        System.out.println("\n=== 热量需求计算 ===");

        double bmr = profileService.calculateBMR(user);
        double dailyNeeds = profileService.calculateDailyCalorieNeeds(user);

        System.out.println("基础代谢率(BMR): " + String.format("%.0f", bmr) + " 千卡/天");
        System.out.println("每日热量需求: " + String.format("%.0f", dailyNeeds) + " 千卡/天");

        // 根据不同目标调整
        double weightLossCalories = dailyNeeds * 0.85; // 减重：减少15%
        double weightGainCalories = dailyNeeds * 1.15; // 增肌：增加15%

        System.out.println("\n基于不同目标的热量建议:");
        System.out.println("减重目标: " + String.format("%.0f", weightLossCalories) + " 千卡/天");
        System.out.println("维持目标: " + String.format("%.0f", dailyNeeds) + " 千卡/天");
        System.out.println("增肌目标: " + String.format("%.0f", weightGainCalories) + " 千卡/天");

        System.out.println("\n按回车键返回...");
        scanner.nextLine();
    }

    // 辅助方法

    private int getActivityLevelCode(String activityLevel) {
        switch (activityLevel) {
            case "久坐": return 1;
            case "轻度活动": return 2;
            case "中度活动": return 3;
            case "重度活动": return 4;
            case "极重度活动": return 5;
            default: return 3;
        }
    }

    private int getTargetCode(String target) {
        switch (target) {
            case "减重": return 1;
            case "维持": return 2;
            case "增肌": return 3;
            default: return 2;
        }
    }

    private double getValidDoubleInput(double min, double max) {
        while (true) {
            try {
                String input = scanner.nextLine().trim();
                double value = Double.parseDouble(input);
                if (value >= min && value <= max) {
                    return value;
                } else {
                    System.out.print("输入值应在 " + min + " 到 " + max + " 之间，请重新输入: ");
                }
            } catch (NumberFormatException e) {
                System.out.print("请输入有效的数字: ");
            }
        }
    }
}